﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InnovTech.Data
{

    public interface IDynamicObjectMember : INamedObject
    {
        string MemberType { get; set; }
        object Value { get; set; }
    }

    public interface IDynamicObject<TMemberKey>
    {
        IDynamicObjectMember this[TMemberKey key] { get; set; }
    }

    

    //public interface IDynamicDomainObject<TType, TKey> : IDynamicObject<TKey> where TType : IDomainObject
    //{
    //    TType ObjectType { get; }
    //}

    public interface IDataObject<TType, TKey> : IDynamicObject<TKey> where TType : IDomainObject
    {
        IList<IBehavior<TType>> ObjectBehaviors { get; }
        IList<IBehavior<T>> GetDataMemberBehavior<T>(TKey memberKey);
        IDataMember<T> GetDataMember<T>(TKey memberKey);
    }

    public interface IDataMember<TMemberType> : IDynamicObjectMember
    {
        TMemberType TypedMemberValue { get; set; }
        IList<IBehavior<TMemberType>> Behaviors { get; }
    }


    public interface IDataConfiguration<TKey> 
    {
        void Set<TType>(IDataObject<TType, TKey> dataObject) where TType : IDomainObject;
        IDataObject<TType, TKey> Get<TType>() where TType : IDomainObject;
        void AddObjectBehavior<TObjectType>(IBehavior<TObjectType> behavior) where TObjectType : IDomainObject;
    }

    public interface IDataObjectHandler<TType, TKey> : IBehavior<IDataObject<TType, TKey>> where TType : IDomainObject
    {
        void Handle(IDataObject<TType, TKey> target);
    }

    #region Interfaces use the type "string" as the key
    public interface IDynamicObject : IDynamicObject<string> { }
    //public interface IDynamicDomainObject<TType> : IDynamicDomainObject<TType, string> where TType : IDomainObject { }
    public interface IDataObject<TType> : IDataObject<TType, string>, IDynamicObject where TType : IDomainObject { }
    public interface IDataConfiguration : IDataConfiguration<string> { }
    public interface IDataObjectHandler<TType> : IDataObjectHandler<TType, string>, IBehavior<IDataObject<TType>> where TType : IDomainObject { }
    #endregion
}
